package com.ruoyi.business.workshop.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ruoyi.business.communication.DeviceCommunicationService;
import com.ruoyi.business.communication.domain.SlotSetting;
import com.ruoyi.business.communication.domain.SlotTiming;
import com.ruoyi.business.device.domain.Device;
import com.ruoyi.business.device.service.IDeviceService;
import com.ruoyi.business.workshop.domain.WorkshopArea;
import com.ruoyi.business.workshop.dto.SlotSettingRequestDTO;
import com.ruoyi.business.workshop.dto.SlotTimingResponseDTO;
import com.ruoyi.business.workshop.dto.WorkshopSlotDTO;
import com.ruoyi.business.workshop.service.WorkshopManagementService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.business.modbus.domain.ModbusWriteResponse;

/**
 * 车间管理控制器
 * 
 * @author ruoyi
 */
@RestController
@RequestMapping("/workshop")
public class WorkshopManagementController extends BaseController {

    @Autowired
    private WorkshopManagementService workshopManagementService;

    @Autowired
    private DeviceCommunicationService deviceCommunicationService;

    @Autowired
    private IDeviceService deviceService;

    /**
     * 获取车间工区列表（不包含状态）
     */
    @PreAuthorize("@ss.hasPermi('workshop:main:view')")
    @GetMapping("/areas")
    public AjaxResult listAreas() {
        try {
            List<WorkshopArea> areas = workshopManagementService.listAreas();
            return AjaxResult.success(areas);
        } catch (Exception e) {
            logger.error("获取车间工区列表失败", e);
            return AjaxResult.error("获取车间工区列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取指定工段的槽位状态
     * 
     * @param sectionName 工段名称
     */
    @PreAuthorize("@ss.hasPermi('workshop:section:view')")
    @GetMapping("/section/{sectionName}/slots")
    public AjaxResult getSectionSlots(@PathVariable String sectionName) {
        try {
            List<WorkshopSlotDTO> slotInfos = workshopManagementService.getSlotsBySection(sectionName);
            return AjaxResult.success(slotInfos);
        } catch (Exception e) {
            logger.error("获取工段槽位状态失败: " + sectionName, e);
            return AjaxResult.error("获取工段槽位状态失败: " + e.getMessage());
        }
    }

    /**
     * 获取指定槽位的时间设置
     * 
     * @param businessSlotNo 业务槽号
     * @return 槽位时间设置信息
     */
    @PreAuthorize("@ss.hasPermi('workshop:slot:view')")
    @GetMapping("/slot/timing")
    public AjaxResult getSlotTiming(@RequestParam Integer businessSlotNo) {
        try {
            if (businessSlotNo == null) {
                return AjaxResult.error("业务槽号不能为空");
            }

            // 根据业务槽号查找设备
            Device device = findDeviceBySlotNumber(businessSlotNo);
            if (device == null) {
                return AjaxResult.error("未找到对应的设备，槽号: " + businessSlotNo);
            }

            // 读取槽位时间设置
            List<SlotTiming> slotTimings = deviceCommunicationService.readSlotTimings(device, businessSlotNo);
            
            if (slotTimings == null || slotTimings.isEmpty()) {
                return AjaxResult.error("未能读取到槽位时间设置，槽号: " + businessSlotNo);
            }

            // 转换为DTO（列表中应该只有一个元素）
            SlotTiming slotTiming = slotTimings.get(0);
            if (slotTiming == null) {
                return AjaxResult.error("未能读取到槽位时间设置，槽号: " + businessSlotNo);
            }
            SlotTimingResponseDTO responseDTO = new SlotTimingResponseDTO(slotTiming);
            
            return AjaxResult.success(responseDTO);
        } catch (Exception e) {
            logger.error("获取槽位时间设置失败，槽号: " + businessSlotNo, e);
            return AjaxResult.error("获取槽位时间设置失败: " + e.getMessage());
        }
    }

    /**
     * 保存槽位设置
     * 
     * @param request 包含槽位设置信息的请求对象
     * @return 保存结果
     */
   //@PreAuthorize("@ss.hasPermi('workshop:slot:edit')")
    @PostMapping("/slot/setting")
    public AjaxResult saveSlotSetting(@RequestBody SlotSettingRequestDTO request) {
        try {
            // 根据业务槽号查找设备
            Device device = findDeviceBySlotNumber(request.getBusinessSlotNo());
            if (device == null) {
                return AjaxResult.error("未找到对应的设备，槽号: " + request.getBusinessSlotNo());
            }

            // 构建SlotSetting对象
            SlotSetting slotSetting = new SlotSetting(request.getBusinessSlotNo());
            slotSetting.setCommandType(SlotSetting.CommandType.fromCode(request.getCommandType()));
            slotSetting.setPositionNumber(SlotSetting.PositionNumber.fromCode(request.getPositionNumber()));
            
            // 根据指令类型设置数据值
            switch (slotSetting.getCommandType()) {
                case ACTION:
                    slotSetting.setActionType(SlotSetting.ActionType.fromCode(request.getActionType()));
                    break;
                case STRIKE_TIME:
                    slotSetting.setStrikeTimeSeconds(request.getStrikeTime());
                    break;
                case POLE_CHANGE_STAGE1:
                    slotSetting.setPoleChangeTimeMinutes(request.getPoleChangeStage1Time());
                    break;
                case POLE_CHANGE_STAGE2:
                    slotSetting.setPoleChangeTimeMinutes(request.getPoleChangeStage2Time());
                    break;
                case AUTO_POLE_NUMBER:
                    slotSetting.setAutoPoleNumber(request.getAutoPoleNumber());
                    break;
                default:
                    return AjaxResult.error("未知指令类型: " + request.getCommandType());
            }

            // 写入设置
            ModbusWriteResponse response = deviceCommunicationService.writeSlotSetting(
                device, slotSetting, false);

            if (response.isSuccess()) {
                return AjaxResult.success("槽位设置保存成功", response);
            } else {
                return AjaxResult.error("槽位设置保存失败: " + response.getMessage());
            }
        } catch (Exception e) {
            logger.error("保存槽位设置失败", e);
            return AjaxResult.error("保存槽位设置失败: " + e.getMessage());
        }
    }

    /**
     * 根据业务槽号查找设备
     */
    private Device findDeviceBySlotNumber(Integer businessSlotNo) {
        if (businessSlotNo == null) {
            return null;
        }
        
        Device queryDevice = new Device();
        List<Device> devices = deviceService.selectDeviceList(queryDevice);
        
        for (Device device : devices) {
            if (device.getStartSlotNumber() != null && device.getEndSlotNumber() != null) {
                if (businessSlotNo >= device.getStartSlotNumber() 
                    && businessSlotNo <= device.getEndSlotNumber()) {
                    return device;
                }
            }
        }
        
        return null;
    }
}
